import { Inject, Provide } from "@midwayjs/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { BblPrizeActivity } from "../entity/prize.activity.entity";
import { BblPrizeGroup } from "../entity/prize.group.entity";
import { BblPrize } from "../entity/prize.entity";
import { BblPrizeResult } from "../entity/prize.result.entity";
import { BblAttach } from "../entity/attach.entity";
import { Utils } from "../utils";
import {
  PrizeActivityCreateDto,
  PrizeActivityPageQueryDto,
  PrizeActivityInfoDto,
  PrizeActivityUpdateDto
} from "../dto/prize.activity.dto";

import { PrizeResultService } from "./prize.result.service";

@Provide()
export class PrizeActivityService {
  @InjectEntityModel(BblPrizeActivity)
  activityRepo: Repository<BblPrizeActivity>;

  @InjectEntityModel(BblPrizeGroup)
  prizeGroupRepo: Repository<BblPrizeGroup>;

  @InjectEntityModel(BblPrize)
  prizeRepo: Repository<BblPrize>;

  @InjectEntityModel(BblPrizeResult)
  resultRepo: Repository<BblPrizeResult>;

  @InjectEntityModel(BblAttach)
  attachRepo: Repository<BblAttach>;

  @Inject()
  utils: Utils;

  @Inject()
  prizeResultService: PrizeResultService;

  async createActivityAndResult(dto: PrizeActivityCreateDto) {
    try {
      // 检查奖品组是否存在
      if (!dto.groupId) {
        return this.utils.service.fail(null, "必须指定奖品组ID");
      }

      // 查询奖品组信息
      const prizeGroup = await this.prizeGroupRepo.findOne({
        where: { id: dto.groupId }
      });

      if (!prizeGroup) {
        return this.utils.service.fail(null, "指定的奖品组不存在");
      }

      // 查询关联的未删除奖品及其权重
      const prizes = await this.prizeRepo.find({
        where: {
          prizeGroup: { id: dto.groupId },
          isDeleted: 0 // 排除已删除的奖品
        }
      });

      if (prizes.length === 0) {
        return this.utils.service.fail(null, "奖品组没有关联的有效奖品");
      }

      // 构建奖品分配映射
      const prizeDistribution: Record<string, number> = {};
      prizes.forEach((prize) => {
        prizeDistribution[prize.id] = prize.weight;
      });

      // 1. 创建活动批次
      const activity = this.activityRepo.create({
        id: this.utils.snowFlake.generate(),
        batchName: dto.batchName,
        batchDesc: dto.batchDesc,
        // 使用奖品组的开始和结束时间
        startTime: prizeGroup.startTime || new Date(),
        endTime: prizeGroup.endTime || new Date(),
        totalCodes: this.prizeResultService.TOTAL_CODES_TO_GENERATE,
        status: 1, // 初始状态为"未开始"
        prizeGroup // 设置奖品组关联
      });

      // 2. 保存活动批次
      const savedActivity = await this.activityRepo.save(activity);

      // 3. 准备抽奖码生成参数
      const prizeResultCreateDto = {
        activityBatchId: savedActivity.id,
        prizeDistribution
      };

      // 4. 调用抽奖码生成服务
      // 注意：这里不使用await，让抽奖码生成在后台异步执行
      this.prizeResultService.batchGenerate(prizeResultCreateDto);

      // 5. 返回创建的活动批次信息
      return this.utils.service.success({
        activityBatch: new PrizeActivityInfoDto(savedActivity),
        message: "活动批次创建成功，抽奖码生成任务已启动"
      });
    } catch (error) {
      return this.utils.service.fail(
        null,
        `创建活动批次失败: ${error.message}`
      );
    }
  }

  // 创建活动批次
  async create(dto: PrizeActivityCreateDto) {
    try {
      // 检查奖品组是否存在
      if (!dto.groupId) {
        return this.utils.service.fail(null, "必须指定奖品组ID");
      }

      // 查询奖品组信息
      const prizeGroup = await this.prizeGroupRepo.findOne({
        where: { id: dto.groupId }
      });

      if (!prizeGroup) {
        return this.utils.service.fail(null, "指定的奖品组不存在");
      }

      // 创建活动批次
      const activity = this.activityRepo.create({
        id: this.utils.snowFlake.generate(),
        batchName: dto.batchName,
        batchDesc: dto.batchDesc,
        // 使用奖品组的开始和结束时间
        startTime: prizeGroup.startTime || new Date(),
        endTime: prizeGroup.endTime || new Date(),
        totalCodes: this.prizeResultService.TOTAL_CODES_TO_GENERATE,
        status: 1, // 初始状态为"未开始"
        prizeGroup // 设置奖品组关联
      });

      const saved = await this.activityRepo.save(activity);
      return this.utils.service.success(new PrizeActivityInfoDto(saved));
    } catch (error) {
      return this.utils.service.fail(
        null,
        `创建活动批次失败: ${error.message}`
      );
    }
  }

  // 分页查询
  // 分页查询条件调整
  async page(query: PrizeActivityPageQueryDto) {
    const qb = this.activityRepo
      .createQueryBuilder("activity")
      .leftJoinAndSelect("activity.prizeGroup", "group");
    // 移除软删除过滤条件
    // .where("activity.isDeleted = 0")

    if (query.batchName) {
      qb.andWhere("activity.batchName LIKE :name", {
        name: `%${query.batchName}%`
      });
    }

    if (query.status) {
      qb.andWhere("activity.status = :status", { status: query.status });
    }

    if (query.groupId) {
      qb.andWhere("group.id = :groupId", { groupId: query.groupId });
    }

    const [list, total] = await qb
      .orderBy("activity.createdAt", "DESC")
      .skip((+query.current - 1) * +query.pageSize)
      .take(+query.pageSize)
      .getManyAndCount();

    return this.utils.service.success({
      total,
      list: list.map((item) => new PrizeActivityInfoDto(item)),
      current: +query.current,
      pageSize: +query.pageSize
    });
  }

  // 更新活动状态
  async updateStatus(id: string, status: number) {
    const result = await this.activityRepo.update({ id }, { status });
    return this.utils.service.success(!!result.affected);
  }

  // 更新活动批次
  async update(dto: PrizeActivityUpdateDto) {
    const activity = await this.activityRepo.findOne({
      where: { id: dto.id }
    });

    if (!activity) {
      return this.utils.service.fail("活动批次不存在");
    }

    // 更新字段
    if (dto.batchName !== undefined) activity.batchName = dto.batchName;
    if (dto.batchDesc !== undefined) activity.batchDesc = dto.batchDesc;
    if (dto.status !== undefined) activity.status = dto.status;
    if (dto.startTime !== undefined)
      activity.startTime = new Date(dto.startTime);
    if (dto.endTime !== undefined) activity.endTime = new Date(dto.endTime);
    if (dto.totalCodes !== undefined) activity.totalCodes = dto.totalCodes;

    // 更新奖品组关联
    if (dto.groupId !== undefined) {
      activity.prizeGroup = dto.groupId
        ? await this.prizeGroupRepo.findOne({
            where: { id: dto.groupId }
          })
        : null;
    }

    const saved = await this.activityRepo.save(activity);
    return this.utils.service.success(new PrizeActivityInfoDto(saved));
  }

  // 删除方法改为物理删除
  async remove(id: string) {
    try {
      // 先查找活动批次，确认存在
      const activity = await this.activityRepo.findOne({
        where: { id }
      });

      if (!activity) {
        return this.utils.service.fail("活动批次不存在");
      }

      // 查询关联的抽奖结果
      const results = await this.resultRepo.find({
        where: { activityBatch: { id } },
        relations: ["qrCode", "trackingAttachment"] // 关联查询二维码和物流单附件
      });

      // 收集所有需要删除的附件ID
      const attachmentIds: string[] = [];
      results.forEach((result) => {
        // 收集二维码附件ID
        if (result.qrCode) {
          attachmentIds.push(result.qrCode.attId);
        }
        // 收集物流单附件ID
        if (result.trackingAttachment) {
          attachmentIds.push(result.trackingAttachment.attId);
        }
      });

      // 删除关联的抽奖结果
      if (results.length > 0) {
        await this.resultRepo.remove(results);
      }

      // 删除关联的附件
      if (attachmentIds.length > 0) {
        await this.attachRepo.delete(attachmentIds);
      }

      // 最后删除活动批次
      await this.activityRepo.delete(id);

      return this.utils.service.success({
        success: true,
        message: `成功删除活动批次及关联的${results.length}个抽奖结果和${attachmentIds.length}个附件`
      });
    } catch (error) {
      return this.utils.service.fail(
        null,
        `删除活动批次失败: ${error.message}`
      );
    }
  }

  // 获取活动详情
  async info(id: string) {
    const activity = await this.activityRepo.findOne({
      where: { id },
      relations: ["prizeGroup"]
    });
    return activity
      ? this.utils.service.success(new PrizeActivityInfoDto(activity))
      : this.utils.service.fail("活动不存在");
  }

  async list(query: { batchName?: string; status?: number; groupId?: string }) {
    const qb = this.activityRepo
      .createQueryBuilder("activity")
      .leftJoinAndSelect("activity.prizeGroup", "group");

    if (query.batchName) {
      qb.andWhere("activity.batchName LIKE :name", {
        name: `%${query.batchName}%`
      });
    }

    if (query.status) {
      qb.andWhere("activity.status = :status", { status: query.status });
    }

    if (query.groupId) {
      qb.andWhere("group.id = :groupId", { groupId: query.groupId });
    }

    const list = await qb.orderBy("activity.createdAt", "DESC").getMany();

    return this.utils.service.success({
      list: list.map((item) => new PrizeActivityInfoDto(item))
    });
  }
}
